package met.cs664.ai.cox.soc.strategies.placement;

import soc.game.SOCBoard;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

/**
 * Scores placements based on accessibility to a 2:1 port in close proximity
 *
 * 1. What resources do I have access to?
 * 2. How frequently will that resource be rolled?
 * 3. How far is the corresponding 2:1 port?
 *
 * @author mcox
 */
public class PortExpansion extends AbstractEvaluator implements PlacementEvaluator {

    public static int ACCESS_TO_PORT = 3;

    public PortExpansion(float weight) {
        super(weight);
    }

    public String toString() {
        return "PortExpansion";
    }

    @Override
    public void evaluateCandidates(SOCBoard board, List<PlacementCandidate> candidates) {
        for (PlacementCandidate candidate : candidates) {
            Map<Integer, Integer> hexToProbability = new HashMap<Integer, Integer>();
            for (int hexCoord : getAdjacentHexesToNode(candidate.getCoord())) {
                int hexType = board.getHexTypeFromCoord(hexCoord);
                int hexProbability = ResourceProbability.DOT_VALUE[board.getNumberOnHexFromCoord(hexCoord)];

                if (hexToProbability.containsKey(hexType)) {
                    hexToProbability.put(hexType, hexToProbability.get(hexType) + hexProbability);
                } else {
                    hexToProbability.put(hexType, hexProbability);
                }
            }

            for (Map.Entry<Integer,Integer> entry : hexToProbability.entrySet()) {
                if (entry.getValue() > 5) {
                    Vector coordsForPortType = board.getPortCoordinates(entry.getKey());
                    int dockOne = (Integer) coordsForPortType.get(0);
                    int dockTwo = (Integer) coordsForPortType.get(1);

                    if (!board.getSettlements().contains(coordsForPortType.get(0))
                            && board.isNode2AwayFromNode(dockOne, candidate.getCoord())) {
                        candidate.updateWeight(getWeight() * ACCESS_TO_PORT);
                    } else if (!board.getSettlements().contains(coordsForPortType.get(1))
                            && board.isNode2AwayFromNode(dockTwo, candidate.getCoord())) {
                        candidate.updateWeight(getWeight() * ACCESS_TO_PORT);
                    }
                }
            }
        }
    }
}
